
/*
 * Nakov Chat Server - (c) Svetlin Nakov, 2002
 *
 * ClientListener class is purposed to listen for client messages and
 * to forward them to ServerDispatcher.
 */
import java.io.*;
import java.net.*;
 
public class ClientListener extends Thread
{
    private ServerDispatcher mServerDispatcher;
    private ClientInfo mClientInfo;
    private BufferedReader mIn;

    public ClientListener(ClientInfo aClientInfo, ServerDispatcher aServerDispatcher)
    throws IOException
    {
        mClientInfo = aClientInfo;
        mServerDispatcher = aServerDispatcher;
        Socket socket = aClientInfo.mSocket;
        mIn = new BufferedReader(new InputStreamReader(socket.getInputStream()));
    }

    /*
     * Until interrupted, reads messages from the client socket, forwards them
     * to the server dispatcher's queue and notifies the server dispatcher.
     */
    public void run()
    {	
        try {
            String msg = "";
            /*
             * Wait for CHAT to start.
             */
            while(true){
                msg = mIn.readLine();
		System.out.println(msg);
                if(msg.matches("CHAT")){
                    mClientInfo.mClientSender.sendMessage("CHAT");
                    break;
                }
                else{
                    throw new IOException("Did not receive CHAT");
                }
            }
            /*
             * Input username before continuing into the chat.
             */
            while(true){
                boolean nameInUse = false;
                msg = mIn.readLine();
                System.out.println(msg);
                if(!msg.matches("USER\\s\\W+") && msg.matches("USER\\s\\w+")){
                    String name = msg.substring(5);
                    if(!(name.length() > 20)){
                        String[] names = mServerDispatcher.UsernameList().split("\\s");
                        for(int i = 0; i < names.length; i++){
                            if(name.matches(names[i])){
                                nameInUse = true;
                                break;
                            }
                        }
                        if(!nameInUse){
                            mClientInfo.UserName = name;
                            mClientInfo.mClientSender.sendMessage("USER");
                            mClientInfo.loggedIn = true;
                            mServerDispatcher.JoinNotify(mClientInfo);
                            break;
                        }
                        else{
                            mClientInfo.mClientSender.sendMessage("INUSE");
                        }
                    }
                    else{
                        mClientInfo.mClientSender.sendMessage("too many" +
                                "characters");
                    }
                }
                else{
                    mClientInfo.mClientSender.sendMessage("something"+
                    "went wrong");
                }
            }
            while(!isInterrupted()){
                msg = mIn.readLine();
                if (msg == null){
                    break;
                }
                else if(msg.matches("NAMES")){
                    mServerDispatcher.dispatchMessage(mClientInfo, msg);
                }
                else if(msg.startsWith("SAY")){
                    mServerDispatcher.dispatchMessage(mClientInfo, msg);
                }
                else if(msg.startsWith("USER ")){
                    mServerDispatcher.dispatchMessage(mClientInfo,msg);
                }
                else if(msg.matches("HELP")){
                    mServerDispatcher.dispatchMessage(mClientInfo, msg);
                }
            }
        } catch (IOException ioex) {
           // Problem reading from socket (communication is broken)
            System.out.println(ioex);
        }

        // Communication is broken. Interrupt both listener and sender threads
        mClientInfo.mClientSender.interrupt();
        mServerDispatcher.deleteClient(mClientInfo);
    }
}